<template>
  <Dialog :title="dialogTitle" v-model="dialogVisible">
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      v-loading="formLoading"
    >
      <!-- 修改后的佐证上传部分 -->
      <el-form-item label="佐证地址" prop="evidenceUrl">
        <el-upload
          :headers="HEADERS"
          :file-list="formData.evidenceUrl"
          class="evidence-upload"
          :action="actionUrl"
          multiple
          list-type="text"
          :on-preview="handlePreview"
          :on-remove="handleRemove"
          :before-remove="beforeRemove"
          :on-success="handleUploadSuccess"
          :on-progress="handleUploadProgress"
          :before-upload="handleBeforeUpload"
          @update:file-list="(files) => formData.evidenceUrl = files"
        >
          <template #trigger>
            <el-button type="primary">文件上传</el-button>
          </template>
          <!-- 添加文件列表显示方式，使链接可点击 -->
          <template #file="{ file }">
            <el-link
              v-if="file.url"
              :href="file.url"
              target="_blank"
              type="primary"
              :underline="false"
            >
              {{ file.name }}
            </el-link>
            <span v-else>{{ file.name }}</span>
            <el-button
      class="delete-icon"
      type="danger"
      link
      :icon="Delete"
      @click.stop="removeFile(file)"
    />
          </template>
          <template #tip>
            <div class="el-upload__tip text-gray-500">
              文件大小不能超过20MB（VPN模式下尽量低于5MB）
            </div>
          </template>
        </el-upload>
        <!-- AI识别按钮 -->
        <el-upload
          :show-file-list="false"
          :before-upload="beforeAIUpload"
          :http-request="handleAIUpload"
          accept="image/*,.pdf,.doc,.docx"
          style="display:inline-block;margin-left:12px;vertical-align:top;"
        >
          <el-button type="success" plain :loading="aiLoading">AI识别填表</el-button>
        </el-upload>
      </el-form-item>
      
      <el-form-item label="论文标题" prop="title">
        <el-input v-model="formData.title" placeholder="请输入论文标题" />
      </el-form-item>
      <el-form-item label="发表时间" prop="postedTime">
        <el-date-picker
          v-model="formData.postedTime"
          type="date"
          value-format="x"
          placeholder="选择发表时间"
        />
      </el-form-item>
      <el-form-item label="发表刊物/论文集" prop="publications">
        <el-input v-model="formData.publications" placeholder="请输入发表刊物/论文集" />
      </el-form-item>
      <el-form-item label="所属单位" prop="affiliation">
        <el-select v-model="formData.affiliation" placeholder="请选择所属单位">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.AFFILIATION)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="作者类型" prop="authorType">
        <el-select v-model="formData.authorType" placeholder="请选择作者类型">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.AUTHOR_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="作者及贡献率" prop="authorList">
        <!-- 修改后的作者列表，类似竞赛管理的成员列表 -->
        <div v-for="(author, index) in formData.authorList" :key="index" class="mb-4">
          <div class="flex items-center gap-4">
            <el-input
              v-model="author.authorName"
              placeholder="请输入作者姓名"
              class="!w-240px"
            />
            <el-input-number
              v-model="author.rate"
              :min="1"
              :max="100"
              :precision="0"
              style="width: 120px;"
              placeholder="贡献率%"
            />
            <el-button
              type="danger"
              link
              :icon="Delete"
              @click="removeAuthor(index)"
              v-if="formData.authorList.length > 1"
            />
          </div>
        </div>
        <el-button type="primary" link @click="addAuthor">
          <Icon icon="ep:plus" class="mr-5px" />添加作者
        </el-button>
      </el-form-item>
      <el-form-item label="论文类型" prop="type">
        <el-select v-model="formData.type" placeholder="请选择论文类型">
          <el-option
            v-for="dict in getIntDictOptions(DICT_TYPE.THESIS_TYPE)"
            :key="dict.value"
            :label="dict.label"
            :value="dict.value"
          />
        </el-select>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
      <el-button @click="dialogVisible = false">取 消</el-button>
    </template>
  </Dialog>
</template>

<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { ThesisApi, ThesisVO } from '@/api/digital/thesis'
import { getAccessToken } from '@/utils/auth'
import { ElMessageBox, ElMessage } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'
import axios from 'axios'
import type { UploadRequestOptions } from 'element-plus'

/** 论文 表单 */
defineOptions({ name: 'ThesisForm' })

const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改
const actionUrl = import.meta.env.VITE_BASE_URL + import.meta.env.VITE_API_URL + '/infra/file/upload'
const HEADERS = { Authorization: 'Bearer ' + getAccessToken() }

// 表单数据
const formData = ref({
  id: undefined,
  title: '',
  postedTime: undefined,
  publications: '',
  affiliation: undefined,
  evidenceUrl: [], // 确保初始值是空数组
  authorType: undefined,
  type: undefined,
  authorList: [{ authorName: '', rate: 100 }] // 初始一个作者
})

// 表单校验规则
const formRules = reactive({
  title: [{ required: true, message: '论文标题不能为空', trigger: 'blur' }],
  postedTime: [{ required: true, message: '发表时间不能为空', trigger: 'blur' }],
  publications: [{ required: true, message: '发表刊物/论文集不能为空', trigger: 'blur' }],
  affiliation: [{ required: true, message: '所属单位不能为空', trigger: 'change' }],
  authorType: [{ required: true, message: '作者类型不能为空', trigger: 'change' }],
  evidenceUrl: [{ required: true, message: '佐证不能为空', trigger: 'change' }],
  type: [{ required: true, message: '论文类型不能为空', trigger: 'change' }],
  authorList: [
    {
      type: 'array',
      required: true,
      validator: (rule, value, callback) => {
        if (!value || value.length === 0) {
          callback(new Error('作者不能为空'))
          return
        }

        // 检查是否所有作者都已填写
        const hasEmptyFields = value.some(
          (author) => !author.authorName || author.rate === undefined
        )
        if (hasEmptyFields) {
          callback(new Error('请填写完整的作者信息和贡献率'))
          return
        }

        // 检查贡献率是否在有效范围内
        const hasInvalidRate = value.some(
          (author) => author.rate < 1 || author.rate > 100
        )
        if (hasInvalidRate) {
          callback(new Error('贡献率必须在1%到100%之间'))
          return
        }

        // 检查是否有重复作者
        const authorNames = value.map(author => author.authorName).filter(name => name !== '')
        const uniqueAuthorNames = new Set(authorNames)
        if (authorNames.length !== uniqueAuthorNames.size) {
          callback(new Error('作者不能重复'))
          return
        }

        // 检查贡献率总和是否为100
        const totalRate = value.reduce((sum, author) => sum + (author.rate || 0), 0)
        if (totalRate !== 100) {
          callback(new Error('贡献率总和必须等于100%'))
          return
        }
        callback()
      },
      trigger: 'change'
    }
  ]
})
const formRef = ref() // 表单 Ref

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = t('action.' + type)
  formType.value = type
  resetForm()
  
  if (id) {
    formLoading.value = true
    try {
      const data = await ThesisApi.getThesis(id)

      // 1. 证据URL处理（增强兼容性）
      if (data.evidenceUrl) {
        // 处理字符串格式的URL数组
        if (typeof data.evidenceUrl === 'string') {
          // 移除首尾方括号、空格和多余的反斜杠
          let arr = data.evidenceUrl
          .replace(/^\[|\]|\\/g, '') // 删除[]和反斜杠
            .split(',')
          .map(s => s.trim().replace(/^"|"$/g, '')) // 移除引号
          
          data.evidenceUrl = arr
            .filter(url => url) // 过滤空值
            .map(url => convertUrlToFileObject(url))
        }
        // 处理原生数组
        else if (Array.isArray(data.evidenceUrl)) {
          data.evidenceUrl = data.evidenceUrl
            .filter(url => url)
            .map(url => typeof url === 'string' 
              ? convertUrlToFileObject(url) 
              : url
            )
        }
      } else {
        data.evidenceUrl = []
      }

      // 2. 作者列表处理（新增转换逻辑）
      if (data.author && data.rate) {
        // 将逗号分隔的字符串转为数组
        const authorNames = data.author.split(',').map(name => name.trim())
        const authorRates = data.rate.split(',').map(rate => {
          const num = parseInt(rate.trim())
          return isNaN(num) ? 0 : num
        })

        // 组合成authorList结构
        data.authorList = authorNames.map((name, index) => ({
          authorName: name,
          rate: authorRates[index] || 0 // 防止越界
        }))
        Object.assign(formData.value, data)
      }
      // 若无作者数据，使用默认结构
      else {
        data.authorList = [{ authorName: '', rate: 100 }]
      }

      formData.value = data
    } finally {
      formLoading.value = false
    }
  }
}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗

/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件，用于操作成功后的回调
const submitForm = async () => {
  // 校验表单
  await formRef.value.validate()
  // 提交请求
  formLoading.value = true
  try {
    // 处理作者和贡献率数据
    const authorNames = formData.value.authorList
      .filter(author => author.authorName)
      .map(author => author.authorName)
    const authorRates = formData.value.authorList
      .filter(author => author.authorName)
      .map(author => author.rate)

    // 处理证据URL
    const evidenceUrls = formData.value.evidenceUrl
      .filter(file => file.response || file.url)
      .map(file => file.response?.data || file.url)
    
    const data = {
      ...formData.value,
      evidenceUrl: evidenceUrls,
      author: authorNames.join(','),      // 将作者姓名数组转换为逗号分隔的字符串
      rate: authorRates.join(',')         // 将贡献率数组转换为逗号分隔的字符串
    } as unknown as ThesisVO
    
    if (formType.value === 'create') {
      await ThesisApi.createThesis(data)
      message.success(t('common.createSuccess'))
    } else {
      await ThesisApi.updateThesis(data)
      message.success(t('common.updateSuccess'))
    }
    dialogVisible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    title: '',
    postedTime: undefined,
    publications: '',
    affiliation: undefined,
    evidenceUrl: [],
    authorType: undefined,
    type: undefined,
    authorList: [{ authorName: '', rate: 100 }]
  }
  formRef.value?.resetFields()
}

const addAuthor = () => {
  formData.value.authorList.push({ authorName: '', rate: 0 })
}
const removeAuthor = (index: number) => {
  formData.value.authorList.splice(index, 1)
  // 如果只剩一个作者，设置其贡献率为100
  if (formData.value.authorList.length === 1) {
    formData.value.authorList[0].rate = 100
  }
}

// 文件上传相关
const handleUploadProgress = (event: any, uploadFile: any) => {
  uploadFile.percentage = Math.round((event.loaded / event.total) * 100)
}

const handleBeforeUpload = (file: File) => {
  const maxSize = 20 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过20MB')
    return false
  }
  return true
}

const handleUploadSuccess = (response: any, uploadFile: any) => {
  if (response.code === 0) {
    const url = response.data
    // 确保设置url属性，而不仅仅是response
    uploadFile.url = url
    uploadFile.name = response.data.split('/').pop() || 'file'
    uploadFile.status = 'success'
    // 清除表单验证错误
    formRef.value?.clearValidate(['evidenceUrl'])
  } else {
    ElMessage.error('上传失败：' + response.msg)
    uploadFile.status = 'error'
  }
}

const handleRemove = (file: any, uploadFiles: any[]) => {
  // 如果没有文件了，重新触发验证
  if (uploadFiles.length === 0) {
    formRef.value?.validateField('evidenceUrl')
  }
}

const handlePreview = (uploadFile: any) => {
  window.open(uploadFile.url)
}

const beforeRemove = async (uploadFile: any, uploadFiles: any[]) => {
  // 如果是因为文件大小超限而被拒绝的文件，直接删除不提示
  if (!uploadFile.url && uploadFile.status === 'ready') {
    return true
  }
  // 正常删除时显示确认提示
  return await ElMessageBox.confirm(`确认删除 ${uploadFile.name} 吗?`)
}

const convertUrlToFileObject = (url: string) => {
  if (!url) return null
  
  // 从URL中提取文件名
  const fileName = url.split('/').pop() || 'file'
  
  return {
    name: fileName,
    url: url,
    status: 'success',
    uid: Date.now() + '_' + Math.random().toString(36).slice(2)
  }
}

// AI识别相关
const aiLoading = ref(false)

// AI识别上传前校验
const beforeAIUpload = (file: File) => {
  const maxSize = 20 * 1024 * 1024
  if (file.size > maxSize) {
    ElMessage.error('文件大小不能超过20MB')
    return false
  }
  return true
}

// AI识别自定义上传
const handleAIUpload = async (options: UploadRequestOptions) => {
  const { file } = options
  aiLoading.value = true
  try {
    const formDataUpload = new FormData()
    formDataUpload.append('file', file)
    
    const res = await axios.post('/ai/thesis', formDataUpload, {
      baseURL: import.meta.env.VITE_BASE_URL,
      headers: { 
        'Content-Type': 'multipart/form-data',
        ...HEADERS,
        'tenant-id': '1'
      }
    })
    
    // 兼容后端返回的msg为字符串的情况
    let aiResult = res.data.data
    if (!aiResult && res.data.msg) {
      try {
        aiResult = JSON.parse(res.data.msg)
      } catch (e) {
        ElMessage.error('AI识别内容解析失败')
        return
      }
    }
    if (res.data && res.data.code === 0 && aiResult) {
      fillFormByAIResult(aiResult)
      ElMessage.success('识别成功，表单已自动填充')
    } else {
      ElMessage.error('识别失败：' + (res.data?.msg || '未知错误'))
    }
  } catch (e) {
    console.error('AI识别失败:', e)
    ElMessage.error('识别失败：' + e.message)
  } finally {
    aiLoading.value = false
  }
}

/** 自定义删除按钮功能 */
const removeFile = (file: any) => {
  // 创建新的文件列表（排除当前文件）
  const newFileList = formData.value.evidenceUrl.filter(
    item => item.uid !== file.uid
  )
  
  // 更新文件列表
  formData.value.evidenceUrl = newFileList
  
  // 触发表单验证
  formRef.value?.validateField('evidenceUrl')
}

// 解析AI识别结果并填充表单
const fillFormByAIResult = (result: any) => {
  // 处理作者数据 - 修改部分开始
  if (result.author) {
    // 检查作者数据是否包含空格（多个作者）
    if (result.author.includes(' ')) {
      // 拆分作者并过滤空值
      const authors = result.author.split(' ').filter((name: string) => name.trim() !== '')
      const authorCount = authors.length
      
      // 计算每个作者的平均贡献率（四舍五入到整数）
      const baseRate = Math.floor(100 / authorCount)
      let remainingRate = 100 - (baseRate * authorCount)
      
      // 创建作者列表
      formData.value.authorList = authors.map((name: string, index: number) => {
        // 调整最后一个作者的贡献率使总和为100%
        const rate = baseRate + (index === authorCount - 1 ? remainingRate : 0)
        return {
          authorName: name.trim(),
          rate: rate
        }
      })
    } else {
      // 单个作者
      formData.value.authorList = [{
        authorName: result.author.trim(),
        rate: 100
      }]
    }
  } else {
    // 没有作者数据时重置为默认
    formData.value.authorList = [{ authorName: '', rate: 100 }]
  }

  // 填充其他字段
  const fieldMap: Record<string, keyof typeof formData.value> = {
    'title': 'title',
    'publications': 'publications',
    'affiliation': 'affiliation',
    'authorType': 'authorType',
    'type': 'type'
  }
  Object.entries(fieldMap).forEach(([aiKey, formKey]) => {
    if (result[aiKey] !== undefined) {
      // @ts-ignore
      formData.value[formKey] = result[aiKey]
    }
  })

  // 处理日期
  if (result.postedTime) {
    const date = new Date(result.postedTime.replace(/-/g, '/'))
    if (!isNaN(date.getTime())) {
      formData.value.postedTime = date.getTime()
    }
  }

  // 处理证据文件
  if (result.evidenceUrl) {
    const urls = Array.isArray(result.evidenceUrl) ? result.evidenceUrl : [result.evidenceUrl]
    formData.value.evidenceUrl = urls.map((url: string) => convertUrlToFileObject(url))
  }
}
</script>

<style scoped>
.evidence-upload {
  width: 360px;
}
</style>